home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / pvlbox.cpp < prev    next >
C/C++ Source or Header  |  1998-01-05  |  22KB  |  983 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW INTERFACE                 |
  4. // |  File:        PVLBOX.CPP                           |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     List box implementation              |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_string
  16. #define uses_dc
  17. #define uses_dialog
  18. #define uses_icons
  19. #define uses_label
  20. #define uses_lbox
  21. #define uses_system
  22.  
  23. #include "PVuses.h"
  24.  
  25. #define SCROLL_AHEAD 1
  26.  
  27. static uint ___data_size;
  28. static Tlb_item_comparator ___comparator;
  29.  
  30. //cmp functions
  31.  
  32. static int cmp_function( const Tlb_item *a, const Tlb_item *b )
  33. {
  34.   return
  35.     strcmp(
  36.       a->data + ___data_size,
  37.       b->data + ___data_size
  38.     );
  39. }
  40.  
  41. static int _cmp_function( const Tlb_item *a, const Tlb_item *b )
  42. {
  43.   return ___comparator( a, b );
  44. }
  45.  
  46. //sort functions
  47.  
  48. static int sort_function( const void *a, const void *b )
  49. {
  50.   return
  51.     strcmp(
  52.       ( *( (Tlb_item **) a ) )->data + ___data_size,
  53.       ( *( (Tlb_item **) b ) )->data + ___data_size
  54.     );
  55. }
  56.  
  57. static int _sort_function( const void *a, const void *b )
  58. {
  59.   return ___comparator( *( (Tlb_item **) a ), *( (Tlb_item **) b ) );
  60. }
  61.  
  62. //search functions
  63.  
  64. static int search_function( const void *a, const void *b )
  65. {
  66.   return
  67.     strcmp(
  68.       ( (Tlb_item *) a )->data + ___data_size,
  69.       ( *( (Tlb_item **) b ) )->data + ___data_size
  70.     );
  71. }
  72.  
  73. static int _search_function( const void *a, const void *b )
  74. {
  75.   return ___comparator( (Tlb_item *) a, *( (Tlb_item **) b ) );
  76. }
  77.  
  78.  
  79. //Tlb_list publics:
  80.  
  81. Tlb_list::Tlb_list( void ):
  82.   Tlist(),
  83.   hsize( _hsize ),
  84.   hbeg_print( _hbeg_print ),
  85.   hmax_print( _hmax_print ),
  86.   hmax_size( _hmax_size ),
  87.   changed( _changed ),
  88.   overflow( _overflow )
  89. {
  90.   items_ptr = (Tlb_arr *) MALLOC( 0x100 * sizeof( Tlb_item * ) );
  91.   scroll_ahead = SCROLL_AHEAD;
  92.   hsize = 0;
  93.   hmax_size = 0;
  94.   hbeg_print = 0;
  95.   data_size = __lsize();
  96.   overflow = 0;
  97.   changed = 1;
  98.   lb_item_killer = __litem_killer();
  99.   lb_item_comparator = __litem_comparator();
  100. }
  101.  
  102. Tlb_list::Tlb_list( Tlb_list *_list ):
  103.   Tlist( _list ),
  104.   hsize( _list->hsize ),
  105.   hbeg_print( _hbeg_print ),
  106.   hmax_print( _hmax_print ),
  107.   hmax_size( _list->hmax_size ),
  108.   changed( _list->changed ),
  109.   overflow( _list->overflow )
  110. {
  111.   hmax_size = 0;
  112.   hbeg_print = 0;
  113.   items_ptr = _list->items_ptr;
  114.   data_size = _list->data_size;
  115.   lb_item_killer = _list->lb_item_killer;
  116.   lb_item_comparator = _list->lb_item_comparator;
  117. }
  118.  
  119. Tlb_list::Tlb_list( uint &v_count, uint &v_current, uint &v_beg_print, int &v_max_print,
  120.                     uint &h_size, uint &h_beg_print, int &h_max_print ):
  121.   Tlist( v_count, v_current, v_beg_print, v_max_print ),
  122.   hsize( h_size ),
  123.   hbeg_print( h_beg_print ),
  124.   hmax_print( h_max_print ),
  125.   hmax_size( _hmax_size ),
  126.   changed( _changed ),
  127.   overflow( _overflow )
  128. {
  129.   items_ptr = (Tlb_arr *)MALLOC( 0x100 * sizeof( Tlb_item * ) );
  130.   scroll_ahead = SCROLL_AHEAD;
  131.   hsize = 0;
  132.   hmax_size = 0;
  133.   hbeg_print = 0;
  134.   data_size = __lsize();
  135.   overflow = 0;
  136.   changed = 1;
  137.   lb_item_killer = __litem_killer();
  138.   lb_item_comparator = __litem_comparator();
  139. }
  140.  
  141. Tlb_list::~Tlb_list( void )
  142. {
  143.   if( !( options & loASSOCIATED ) )
  144.   {
  145.     clear();
  146.     if( items_ptr != NULL ) FREE( items_ptr );
  147.   }
  148. }
  149.  
  150. void Tlb_list::clear( void )
  151. {
  152.   if( items_ptr != NULL )
  153.     for( uint i = 0; i < vcount; i++ )
  154.       free_lb_item( (*items_ptr)[i] );
  155.   hsize = 0;
  156.   hmax_size = 0;
  157.   hbeg_print = 0;
  158.   overflow = 0;
  159.   changed = 1;
  160.   Tlist::clear();
  161. }
  162.  
  163. uint Tlb_list::add( void *data )
  164. {
  165.   Tlb_item *p;
  166.   int (* cmp) ( const Tlb_item *, const Tlb_item * );
  167.   int m, l, r, x;
  168.  
  169.   if( overflow ) return (uint) -1;
  170.   p = alloc_lb_item( (char *) data );
  171.   if( p == NULL )
  172.   {
  173.     overflow = 1;
  174.     return (uint) -1;
  175.   }
  176.   inc_count();
  177.   if( overflow )
  178.   {
  179.     free_lb_item( p );
  180.     return (uint) -1;
  181.   }
  182.   l = vcount - 1;
  183.   if( ( vcount > 1 ) && ( options & loSORTED ) )
  184.   {
  185.     cmp = cmp_function;
  186.     if( lb_item_comparator != NULL ) cmp = _cmp_function;
  187.     ___data_size = data_size;
  188.     ___comparator = lb_item_comparator;
  189.     l = 0; r = vcount - 2;
  190.     while( l <= r )
  191.     {
  192.       m = ( l + r ) / 2;
  193.       x = cmp( (*items_ptr)[m], p );
  194.       if( x == 0 )
  195.       {
  196.         l = m;
  197.         break;
  198.       }
  199.       if( x < 0 ) { l = m+1; continue; }
  200.       if( x > 0 ) r = m-1;
  201.     }
  202.     if( l < ( vcount - 1 ) )
  203.       memmove( &( (*items_ptr)[l + 1] ), &( (*items_ptr)[l] ), (vcount - l - 1) * sizeof( Tlb_item * ) );
  204.   }
  205.   (*items_ptr)[l] = p;
  206.   at( l );
  207.   changed = 1;
  208.   return l;
  209. }
  210.  
  211. void Tlb_list::ins( uint i, void *data )
  212. {
  213.   Tlb_item *lbi;
  214.  
  215.   if( overflow ) return;
  216.   if( i >= vcount )
  217.     add( data );
  218.   else
  219.   {
  220.     lbi = alloc_lb_item( (char *) data );
  221.     if( lbi == NULL )
  222.     {
  223.       overflow = 1;
  224.       return;
  225.     }
  226.     inc_count();
  227.     if( overflow ) return;
  228.     memmove( &( (*items_ptr)[i + 1] ), &( (*items_ptr)[i] ), (vcount - i - 1) * sizeof( Tlb_item * ) );
  229.     (*items_ptr)[i] = lbi;
  230.   }
  231.   changed = 1;
  232. }
  233.  
  234. void Tlb_list::del( uint i )
  235. {
  236.   if( ( i >= vcount ) || !vcount ) return;
  237.   free_lb_item( (*items_ptr)[i] );
  238.   memmove( &( (*items_ptr)[i] ), &( (*items_ptr)[i+1] ), (vcount - i - 1) * sizeof( Tlb_item * ) );
  239.   dec_count();
  240.   if( vcurrent >= vcount ) bottom();
  241.   overflow = 0;
  242.   changed = 1;
  243. }
  244.  
  245. void Tlb_list::get( uint i, void *data )
  246. {
  247.   Tlb_item *p;
  248.  
  249.   if( i >= vcount ) return;
  250.   p = (*items_ptr)[i];
  251.   memmove( data, p->data, data_size );
  252.   strcpy( ( (char *) data ) + data_size, p->data+data_size );
  253. }
  254.  
  255. void Tlb_list::put( uint i, void *data )
  256. {
  257.   Tlb_item *n;
  258.  
  259.   if( i >= vcount ) return;
  260.   n = alloc_lb_item( (char *) data );
  261.   if( n == NULL )
  262.   {
  263.     overflow = 1;
  264.     return;
  265.   }
  266.   free_lb_item( (*items_ptr)[i] );
  267.   (*items_ptr)[i] = n;
  268.   changed = 1;
  269. }
  270.  
  271. void Tlb_list::sort( void )
  272. {
  273.   sort_range( 0, vcount );
  274. }
  275.  
  276. void Tlb_list::sort_range( uint from, uint how_many )
  277. {
  278.   int (* sort_func) ( const void *, const void * );
  279.  
  280.   sort_func = sort_function;
  281.   if( lb_item_comparator != NULL ) sort_func = _sort_function;
  282.   ___data_size = data_size;
  283.   ___comparator = lb_item_comparator;
  284.   qsort( *items_ptr + from, how_many, sizeof( Tlb_item * ), sort_func );
  285. }
  286.  
  287. uint Tlb_list::bin_search( Tlb_item *p )
  288. {
  289.   return bin_search_range( p, 0, vcount );
  290. }
  291.  
  292. uint Tlb_list::bin_search_range( Tlb_item *p, uint from, uint how_many )
  293. {
  294.   int (* search_func) ( const void *, const void * );
  295.   Tlb_item **key;
  296.  
  297.   search_func = search_function;
  298.   if( lb_item_comparator != NULL ) search_func = _search_function;
  299.   ___data_size = data_size;
  300.   ___comparator = lb_item_comparator;
  301.   key = (Tlb_item **) bsearch( p, *items_ptr + from, how_many, sizeof( Tlb_item * ), search_func );
  302.   if( key == NULL ) return -1;
  303.   return key - *items_ptr;
  304. }
  305.  
  306. void Tlb_list::up( void )
  307. {
  308.   uint i, j;
  309.  
  310.   if( !vcount ) return;
  311.   i = vcurrent; j = vbeg_print;
  312.   Tlist::up();
  313.   while( !enabled( vcurrent ) && vcurrent ) Tlist::up();
  314.   if( !enabled( vcurrent ) )
  315.   {
  316.     vcurrent = i;
  317.     vbeg_print = j;
  318.   }
  319. }
  320.  
  321. void Tlb_list::down( void )
  322. {
  323.   uint i, j;
  324.  
  325.   if( !vcount ) return;
  326.   i = vcurrent; j = vbeg_print;
  327.   Tlist::down();
  328.   while( !enabled( vcurrent ) && ( vcurrent < ( vcount - 1 ) ) ) Tlist::down();
  329.   if( !enabled( vcurrent ) )
  330.   {
  331.     vcurrent = i;
  332.     vbeg_print = j;
  333.   }
  334. }
  335.  
  336. void Tlb_list::top( void )
  337. {
  338.   if( !vcount ) return;
  339.   Tlist::top();
  340.   while( !enabled( vcurrent ) && ( vcurrent < ( vcount - 1 ) ) ) Tlist::down();
  341. }
  342.  
  343. void Tlb_list::bottom( void )
  344. {
  345.   if( !vcount ) return;
  346.   Tlist::bottom();
  347.   while( !enabled( vcurrent ) && vcurrent ) Tlist::up();
  348.